package utils

import (
	"fmt"
	"log"
	"os"
	"path/filepath"
	"runtime"
)

// 日志级别
type LogLevel int

const (
	LogLevelDebug LogLevel = iota
	LogLevelInfo
	LogLevelWarn
	LogLevelError
)

// Logger 日志管理器
type Logger struct {
	level      LogLevel
	fileLogger *log.Logger
	stdout     *log.Logger
	file       *os.File
}

var (
	globalLogger *Logger
)

// InitLogger 初始化全局日志器
func InitLogger(level string, filename string) error {
	logLevel := parseLogLevel(level)

	logger := &Logger{
		level:  logLevel,
		stdout: log.New(os.Stdout, "", log.LstdFlags),
	}

	// 如果指定了日志文件，创建文件日志器
	if filename != "" {
		// 确保目录存在
		dir := filepath.Dir(filename)
		if err := os.MkdirAll(dir, 0755); err != nil {
			return fmt.Errorf("创建日志目录失败: %w", err)
		}

		file, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
		if err != nil {
			return fmt.Errorf("打开日志文件失败: %w", err)
		}

		logger.file = file
		logger.fileLogger = log.New(file, "", log.LstdFlags)
	}

	globalLogger = logger
	return nil
}

// GetLogger 获取全局日志器
func GetLogger() *Logger {
	if globalLogger == nil {
		// 如果没有初始化，使用默认配置
		InitLogger("info", "")
	}
	return globalLogger
}

// Close 关闭日志器
func (l *Logger) Close() error {
	if l.file != nil {
		return l.file.Close()
	}
	return nil
}

// log 内部日志方法
func (l *Logger) log(level LogLevel, format string, args ...interface{}) {
	if level < l.level {
		return
	}

	// 获取调用者信息
	_, file, line, ok := runtime.Caller(2)
	if ok {
		file = filepath.Base(file)
	} else {
		file = "unknown"
		line = 0
	}

	// 格式化消息
	levelStr := logLevelString(level)
	message := fmt.Sprintf(format, args...)
	logMsg := fmt.Sprintf("[%s] %s:%d %s", levelStr, file, line, message)

	// 输出到控制台
	l.stdout.Println(logMsg)

	// 输出到文件
	if l.fileLogger != nil {
		l.fileLogger.Println(logMsg)
	}
}

// Debug 调试日志
func (l *Logger) Debug(format string, args ...interface{}) {
	l.log(LogLevelDebug, format, args...)
}

// Info 信息日志
func (l *Logger) Info(format string, args ...interface{}) {
	l.log(LogLevelInfo, format, args...)
}

// Warn 警告日志
func (l *Logger) Warn(format string, args ...interface{}) {
	l.log(LogLevelWarn, format, args...)
}

// Error 错误日志
func (l *Logger) Error(format string, args ...interface{}) {
	l.log(LogLevelError, format, args...)
}

// 全局便捷方法
func Debug(format string, args ...interface{}) {
	GetLogger().Debug(format, args...)
}

func Info(format string, args ...interface{}) {
	GetLogger().Info(format, args...)
}

func Warn(format string, args ...interface{}) {
	GetLogger().Warn(format, args...)
}

func Error(format string, args ...interface{}) {
	GetLogger().Error(format, args...)
}

// parseLogLevel 解析日志级别
func parseLogLevel(level string) LogLevel {
	switch level {
	case "debug":
		return LogLevelDebug
	case "info":
		return LogLevelInfo
	case "warn":
		return LogLevelWarn
	case "error":
		return LogLevelError
	default:
		return LogLevelInfo
	}
}

// logLevelString 获取日志级别字符串
func logLevelString(level LogLevel) string {
	switch level {
	case LogLevelDebug:
		return "DEBUG"
	case LogLevelInfo:
		return "INFO"
	case LogLevelWarn:
		return "WARN"
	case LogLevelError:
		return "ERROR"
	default:
		return "UNKNOWN"
	}
}
